﻿using System;
using System.Collections;
using System.DirectoryServices;
using System.Globalization;
using System.Linq;
using Framework.IISUtility;

namespace Framework
{
    public class IISManagement
    {
        internal static string Machinename = "localhost";
        /// <summary>
        ///
        /// </summary>
        public IISWebServerCollection WebServers = new IISWebServerCollection();
        /// <summary>
        ///
        /// </summary>
        public IISManagement()
        {
            start();
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="MachineName">机器名,默认值为localhost</param>
        public IISManagement(string MachineName)
        {
            if (MachineName != "")
                Machinename = MachineName;
            start();
        }
        /// <summary>
        ///  地址池管理
        /// </summary>
        /// <param name="appPoolName">地址池名称</param>
        /// <param name="method">当method="Recycle"时就是回收，为“Start”时是启动，为“Stop”时是停止。</param>
        /// <returns></returns>
        public static string StartStopRecycleApp(string appPoolName, string method)
        {
            try
            {
                var appPool = new DirectoryEntry("IIS://localhost/W3SVC/AppPools");
                DirectoryEntry findPool = appPool.Children.Find(appPoolName, "IIsApplicationPool");
                findPool.Invoke(method, null);
                appPool.CommitChanges();
                appPool.Close();
                return string.Format("应用程序池{0}{1}成功", appPoolName, method);
            }
            catch (Exception ex)
            {
                return string.Format("应用程序池{0}{2}失败:{1}", appPoolName, ex.Message, method);
            }
        }

        public static void ModifyScriptMaps(string virtualDirName, string port)
        {
            const string iiSWebSiteRoot = "IIS://localhost/W3SVC/1/ROOT";

            var root = new DirectoryEntry(iiSWebSiteRoot);
            //创建虚拟目录
            DirectoryEntry tbEntry = root.Children.Add(virtualDirName, root.SchemaClassName);
            //ScriptMaps原有属性值
            var mappings = (Object[])tbEntry.InvokeGet("ScriptMaps");
            ArrayList list = AddScriptArray();
            var list2 = new ArrayList();
            foreach (string s in mappings)
            {
                if (!list.Contains(s))
                {
                    list2.Add(s);
                }
            }
            list2.AddRange(list);
            //ScriptMaps更改属性值
            tbEntry.Properties["ScriptMaps"].Value = list2.ToArray();
            tbEntry.CommitChanges();
            //修改IIS端口号
            var folderRoot = new DirectoryEntry("IIS://localhost/W3SVC/1");
            //得到默认站点的IP 端口 描述       
            string strServerBindings = folderRoot.Properties["ServerBindings"].Value.ToString();
            //解出端口Port
            char[] splitChar = { ':' };
            string[] strArr = strServerBindings.Split(splitChar);
            //重新赋值为8000
            folderRoot.Properties["ServerBindings"].Value = strArr[0] + ":" + port + ":" + strArr[2];

            folderRoot.CommitChanges();
        }
        public static ArrayList AddScriptArray()
        {
            var list = new ArrayList();
            string[] array = { ".ascx", ".asmx", ".aspx", ".config", ".mvc" };
            foreach (string t in array)
            {
                list.Add(t + @",c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll,5,GET,HEAD,POST,DEBUG");
                //默认5代表检查索引，1不检查
            }
            return list;
        }
        private void start()
        {
            var Service = new DirectoryEntry("IIS://" + Machinename + "/W3SVC");
            DirectoryEntry Root = null;
            IEnumerator ie = Service.Children.GetEnumerator();
            bool finded = false;
            while (ie.MoveNext())
            {
                var Server = (DirectoryEntry)ie.Current;
                if (Server != null && Server.SchemaClassName == "IIsWebServer")
                {
                    var item = new IISWebServer
                                   {
                                       index = Convert.ToInt32(Server.Name),
                                       ServerComment = (string)Server.Properties["ServerComment"][0],
                                       AccessRead = (bool)Server.Properties["AccessRead"][0],
                                       AccessScript = (bool)Server.Properties["AccessScript"][0],
                                       DefaultDoc = (string)Server.Properties["DefaultDoc"][0],
                                       EnableDefaultDoc = (bool)Server.Properties["EnableDefaultDoc"][0],
                                       EnableDirBrowsing = (bool)Server.Properties["EnableDirBrowsing"][0]
                                   };

                    IEnumerator ieRoot = Server.Children.GetEnumerator();

                    while (ieRoot.MoveNext())
                    {
                        Root = (DirectoryEntry)ieRoot.Current;
                        if (Root != null && Root.SchemaClassName == "IIsWebVirtualDir")
                        {
                            finded = true;
                            break;
                        }
                    }
                    if (finded)
                    {
                        if (Root != null) item.Path = Root.Properties["path"][0].ToString();
                    }

                    item.Port =
                        Convert.ToInt32(((string)Server.Properties["Serverbindings"][0]).Substring(1,
                                                                                                    ((string)
                                                                                                     Server.Properties[
                                                                                                         "Serverbindings"
                                                                                                         ][0]).Length -
                                                                                                    2));
                    WebServers.Add_(item);
                    if (Root != null)
                    {
                        ieRoot = Root.Children.GetEnumerator();
                        while (ieRoot.MoveNext())
                        {
                            var VirDir = (DirectoryEntry)ieRoot.Current;
                            if (VirDir != null && (VirDir.SchemaClassName != "IIsWebVirtualDir" && VirDir.SchemaClassName != "IIsWebDirectory"))
                                continue;
                            var item_virdir = new IISWebVirtualDir(item.ServerComment);
                            if (VirDir != null)
                            {
                                item_virdir.Name = VirDir.Name;
                                item_virdir.AccessRead = (bool)VirDir.Properties["AccessRead"][0];
                                item_virdir.AccessScript = (bool)VirDir.Properties["AccessScript"][0];
                                item_virdir.DefaultDoc = (string)VirDir.Properties["DefaultDoc"][0];
                                item_virdir.EnableDefaultDoc = (bool)VirDir.Properties["EnableDefaultDoc"][0];
                                if (VirDir.SchemaClassName == "IIsWebVirtualDir")
                                {
                                    item_virdir.Path = (string)VirDir.Properties["Path"][0];
                                }
                                else if (VirDir.SchemaClassName == "IIsWebDirectory")
                                {
                                    item_virdir.Path = Root.Properties["Path"][0] + @"\" + VirDir.Name;
                                }
                            }
                            item.WebVirtualDirs.Add_(item_virdir);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 创建站点
        /// </summary>
        /// <param name="iisServer"></param>
        public static void CreateIISWebServer(IISWebServer iisServer)
        {
            if (iisServer.ServerComment == "")
                throw (new Exception("IISWebServer的ServerComment不能为空!"));
            var Service = new DirectoryEntry("IIS://" + Machinename + "/W3SVC");
            DirectoryEntry Server;
            int i = 0;
            IEnumerator ie = Service.Children.GetEnumerator();

            while (ie.MoveNext())
            {
                Server = (DirectoryEntry)ie.Current;
                if (Server != null && Server.SchemaClassName == "IIsWebServer")
                {
                    if (Convert.ToInt32(Server.Name) > i)
                        i = Convert.ToInt32(Server.Name);
                }
            }
            i++;
            iisServer.index = i;
            Server = Service.Children.Add(i.ToString(CultureInfo.InvariantCulture), "IIsWebServer");
            Server.Properties["ServerComment"][0] = iisServer.ServerComment;
            Server.Properties["Serverbindings"].Add(":" + iisServer.Port + ":");
            Server.Properties["AccessScript"][0] = iisServer.AccessScript;
            Server.Properties["AccessRead"][0] = iisServer.AccessRead;
            Server.Properties["EnableDirBrowsing"][0] = iisServer.EnableDirBrowsing;
            Server.Properties["DefaultDoc"][0] = iisServer.DefaultDoc;
            Server.Properties["EnableDefaultDoc"][0] = iisServer.EnableDefaultDoc;
            DirectoryEntry root = Server.Children.Add("Root", "IIsWebVirtualDir");
            root.Properties["path"][0] = iisServer.Path;
            Service.CommitChanges();
            Server.CommitChanges();
            root.CommitChanges();
            root.Invoke("AppCreate2", new object[] { 2 });
        }

        /// <summary>
        /// 删除IISWebServer
        /// </summary>
        public static void RemoveIISWebServer(string ServerComment)
        {
            var Service = new DirectoryEntry("IIS://" + Machinename + "/W3SVC");
            IEnumerator ie = Service.Children.GetEnumerator();
            ServerComment = ServerComment.ToLower();
            while (ie.MoveNext())
            {
                var Server = (DirectoryEntry)ie.Current;
                if (Server != null && Server.SchemaClassName == "IIsWebServer")
                {
                    if (Server.Properties["ServerComment"][0].ToString().ToLower() == ServerComment)
                    {
                        Service.Children.Remove(Server);
                        Service.CommitChanges();
                        return;
                    }
                }
            }
        }


        /// <summary>
        /// 删除IISWebServer
        /// </summary>
        public static void RemoveIISWebServer(int index)
        {
            var Service = new DirectoryEntry("IIS://" + Machinename + "/W3SVC");
            try
            {
                var Server = new DirectoryEntry("IIS://" + Machinename + "/W3SVC/" + index);
                Service.Children.Remove(Server);
                Service.CommitChanges();
            }
            catch
            {
                throw (new Exception("找不到此IISWebServer"));
            }
        }


        /// <summary>
        /// 检查是否存在IISWebServer
        /// </summary>
        /// <param name="ServerComment">网站说明</param>
        /// <returns></returns>
        public static bool ExistsIISWebServer(string ServerComment)
        {
            ServerComment = ServerComment.Trim();
            var Service = new DirectoryEntry("IIS://" + Machinename + "/W3SVC");
            IEnumerator ie = Service.Children.GetEnumerator();

            while (ie.MoveNext())
            {
                var Server = (DirectoryEntry)ie.Current;
                if (Server != null && Server.SchemaClassName == "IIsWebServer")
                {
                    string comment = Server.Properties["ServerComment"][0].ToString().ToLower().Trim();
                    if (comment == ServerComment.ToLower())
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// 返回指定的IISWebServer
        /// </summary>
        /// <param name="ServerComment"></param>
        /// <returns></returns>
        internal static DirectoryEntry returnIISWebserver(string ServerComment)
        {
            ServerComment = ServerComment.Trim();
            var Service = new DirectoryEntry("IIS://" + Machinename + "/W3SVC");
            IEnumerator ie = Service.Children.GetEnumerator();

            while (ie.MoveNext())
            {
                var Server = (DirectoryEntry)ie.Current;
                if (Server != null && Server.SchemaClassName == "IIsWebServer")
                {
                    string comment = Server.Properties["ServerComment"][0].ToString().ToLower().Trim();
                    if (comment == ServerComment.ToLower())
                    {
                        return Server;
                    }
                }
            }

            return null;
        }


        /// <summary>
        ///  返回指定的IISWebServer
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        internal static DirectoryEntry returnIISWebserver(int index)
        {
            var Server = new DirectoryEntry("IIS://" + Machinename + "/W3SVC/" + index);
            try
            {
                Server.Children.GetEnumerator();
                return Server;
            }
            catch
            {
                return null;
            }
        }

        private static DirectoryEntry getRoot(DirectoryEntry Server)
        {
            return (from DirectoryEntry child in Server.Children let name = child.Name.ToLower() where name == "iiswebvirtualdir" || name == "root" select child).FirstOrDefault();
        }


        /// <summary>
        /// 修改与给定的IISWebServer具有相同网站说明的站点配置
        /// </summary>
        /// <param name="iisServer">给定的IISWebServer</param>
        public static void EditIISWebServer(IISWebServer iisServer)
        {
            if (iisServer.index == -1)
                throw (new Exception("找不到给定的站点!"));
            var Service = new DirectoryEntry("IIS://" + Machinename + "/W3SVC");
            DirectoryEntry Server;

            IEnumerator ie = Service.Children.GetEnumerator();

            while (ie.MoveNext())
            {
                Server = (DirectoryEntry)ie.Current;
                if (Server != null && Server.SchemaClassName == "IIsWebServer")
                {
                    if (Server.Properties["Serverbindings"][0].ToString() == ":" + iisServer.Port + ":")
                    {
                        Server.Invoke("stop", new object[0]);
                    }
                }
            }

            Server = returnIISWebserver(iisServer.index);
            if (Server == null)
            {
                throw (new Exception("找不到给定的站点!"));
            }

            Server.Properties["ServerComment"][0] = iisServer.ServerComment;
            Server.Properties["Serverbindings"][0] = ":" + iisServer.Port + ":";
            Server.Properties["AccessScript"][0] = iisServer.AccessScript;
            Server.Properties["AccessRead"][0] = iisServer.AccessRead;
            Server.Properties["EnableDirBrowsing"][0] = iisServer.EnableDirBrowsing;
            Server.Properties["DefaultDoc"][0] = iisServer.DefaultDoc;
            Server.Properties["EnableDefaultDoc"][0] = iisServer.EnableDefaultDoc;
            DirectoryEntry root = getRoot(Server);
            Server.CommitChanges();
            if (root != null)
            {
                root.Properties["path"][0] = iisServer.Path;
                root.CommitChanges();
            }
            Server.Invoke("start", new object[0]);
        }

        /// <summary>
        /// 返回所有站点的网站说明
        /// </summary>
        /// <returns></returns>
        public static ArrayList returnIISServerComment()
        {
            var Service = new DirectoryEntry("IIS://" + Machinename + "/W3SVC");
            var list = new ArrayList();
            IEnumerator ie = Service.Children.GetEnumerator();
            while (ie.MoveNext())
            {
                var Server = (DirectoryEntry)ie.Current;
                if (Server != null && Server.SchemaClassName == "IIsWebServer")
                {
                    list.Add(Server.Properties["ServerComment"][0]);
                }
            }

            return list;
        }


        /// <summary>
        /// 创建虚拟目录
        /// </summary>
        /// <param name="iisVir"></param>
        /// <param name="deleteIfExist"></param>
        public static void CreateIISWebVirtualDir(IISWebVirtualDir iisVir, bool deleteIfExist)
        {
            if (iisVir.Parent == null)
                throw (new Exception("IISWebVirtualDir没有所属的IISWebServer!"));
            DirectoryEntry Server = returnIISWebserver(iisVir.Parent.index);
            if (Server == null)
            {
                throw (new Exception("找不到给定的站点!"));
            }
            Server = getRoot(Server);
            if (deleteIfExist)
            {
                foreach (DirectoryEntry VirDir in Server.Children)
                {
                    if (VirDir.Name.ToLower().Trim() == iisVir.Name.ToLower())
                    {
                        Server.Children.Remove(VirDir);
                        Server.CommitChanges();
                        break;
                    }
                }
            }

            DirectoryEntry vir = Server.Children.Add(iisVir.Name, "IIsWebVirtualDir");
            vir.Properties["Path"][0] = iisVir.Path;
            vir.Properties["DefaultDoc"][0] = iisVir.DefaultDoc;
            vir.Properties["EnableDefaultDoc"][0] = iisVir.EnableDefaultDoc;
            vir.Properties["AccessScript"][0] = iisVir.AccessScript;
            vir.Properties["AccessRead"][0] = iisVir.AccessRead;
            vir.Invoke("AppCreate2", new object[] { 2 });
            Server.CommitChanges();
            vir.CommitChanges();
        }


        /// <summary>
        /// 删除虚拟目录
        /// </summary>
        /// <param name="WebServerComment">站点说明</param>
        /// <param name="VirtualDir">虚拟目录名称</param>
        public static void RemoveIISWebVirtualDir(string WebServerComment, string VirtualDir)
        {
            VirtualDir = VirtualDir.ToLower();
            DirectoryEntry Server = returnIISWebserver(WebServerComment);
            if (Server == null)
            {
                throw (new Exception("找不到给定的站点!"));
            }
            Server = getRoot(Server);
            foreach (DirectoryEntry VirDir in Server.Children)
            {
                if (VirDir.Name.ToLower().Trim() == VirtualDir)
                {
                    Server.Children.Remove(VirDir);
                    Server.CommitChanges();
                    return;
                }
            }

            throw (new Exception("找不到给定的虚拟目录!"));
        }

        /// <summary>
        /// 删除虚拟目录
        /// </summary>
        /// <param name="iisVir"></param>
        public static void RemoveIISWebVirtualDir(IISWebVirtualDir iisVir)
        {
            DirectoryEntry Server = returnIISWebserver(iisVir.Parent.index);
            if (Server == null)
            {
                throw (new Exception("找不到给定的站点!"));
            }
            Server = getRoot(Server);
            foreach (DirectoryEntry VirDir in Server.Children)
            {
                if (VirDir.Name.ToLower().Trim() == iisVir.Name.ToLower())
                {
                    Server.Children.Remove(VirDir);
                    Server.CommitChanges();
                    return;
                }
            }

            throw (new Exception("找不到给定的虚拟目录!"));
        }
    }
}